Trashegimia e klasave

Ne menyre qe te shmangim perseritjen e kodit dhe per ta bere nje aplikacion sa me fleksibel dhe te lehte per t'u mirembajtur na vjen ne ndihme trashegimia e klasave. Ne shume raste, objekte te jetes reale kane gjera te perbashketa midis tyre. P.sh. le te supozojme se kemi nje qen dhe nje zog, dy objekte te ndryshme te cilat duhet t'i paraqesim ne nje program kompjuterik. Fillimisht ndertojme nje klase per objektin qen:

<?php

clas Qen {

    public $ngjyra;
    public $madhesia;

    function merr_frym() {
        print ("Thith oksigjenin qe ndodhet ne ajer.");
    }

    function ecen() {
        print("Ecen ne toke.");
    }
}

Ndertojme dhe nje klase per objektin zog:

<?php

clas Zog {

    public $ngjyra;
    public $madhesia;

    function merr_frym() {
        print ("Thith oksigjenin qe ndodhet ne ajer.");
    }

    function fluturon() {
        print("Fluturon ne qiell.");
    }
}

Duke pare me kujdes dy klasat e mesiperme veme re qe shume kod perseritet si tek nje klase ashtu edhe tek tjetra. Perseritja e kodit eshte shume e demshme per nje aplikacion me kualitet pasi ul fleksibilitetit dhe veshtireson permbajtjen. P.sh. Ne rast ne funksionin merr_frym duam te ndryshojme tekstin nga Thith oksigjenin qe ndodhet ne ajer. ne Thith oksigjenin ne ajer. atehere ne duhet te shkojme tek njera klase te bejme ndryshimin, dhe me pas te shkojme tek klasa tjeter te bejme edhe aty ndryshimin. Imagjino sikur kjo te ndodhej ne qindra klasa te ndryshme dhe te na duhej te ndryshonim qindra klasa me radhe. Duke shume e bezdisshme dhe lodhese. Per te shmangur kete ne vjen ne ndihme trashegimia e klasave, ku gjerat e perbashketa i percaktojme ne nje klase prind dhe gjerat e vecanta i ndajme ne klasa femije te vecanta.

Le te ndertojme nje klase baze me emrin Kafshe:

<?php

clas Kafshe {

    public $ngjyra;
    public $madhesia;

    function merr_frym() {
        print ("Thith oksigjenin qe ndodhet ne ajer.");
    }
}

Kodin qe perseritej me lart e kemi deklaruar ne nje klase baze te quajtur Kafshe. Me poshte do te deklarojme klasat femije, te cilat do te trashegojne klasen Kafshe:

<?php

clas Qen extends Kafshe {

    function ecen() {
        print("Ecen ne toke.");
    }
}
<?php

clas Zog extends Kafshe {

    function fluturon() {
        print("Fluturon ne qiell.");
    }
}

Pra, ne klasat femije kemi deklaruar vetem funksionet anetare qe nuk perseriten dhe qe jane te vecanta per cdo tip objekti. Ne rreshtin e deklarimit te klases clas Zog extends Kafshe perdoret termi extends shoqeruar me emrin e klases prind per te trasheguar nje klase te caktuar.

Klasa Qen dhe Zog, te cilat jane klasa femije, mund te perdorin lehtesisht funksionet dhe variablat anetare qe ndodhen brenda klases Kafshe ne te njejten menyre sikur te ishin te deklaruara ne brendesi te tyre. Kjo perben dhe konceptin e trashegimise, ku dy klasat Qen dhe Zog trashegojne gjithcka nga klasa prind Kafshe.

Shembull:

<?php

$qen = new Qen();

$qen->ecen();

$qen->merr_frym();

$qen->ngjyra = "E Zeze";

Pasi kemi krijuar objektin $qen, shohim qe ashtu sic mund te therrasim funksionin $qen->ecen(); i cili ndodhet brenda klases Qen, ne te njejten menyre therrasim edhe funksionin $qen->merr_frym(); te trasheguar nga klasa prind Kafshe. Po ashtu aksesojme edhe variablat anetare te klases prind $qen->ngjyra = "E Zeze";, ne te njejten menyre sikur te ishin brenda klases Qen, pasi ajo i trashegon.

E njejta gje ndodh edhe me objektet e tipit Zog:

<?php

$zog = new Zog();

$zog->fluturon();

$zog->merr_frym();

$zog->ngjyra = "E Bardhe";

Koncepti 'Function Overriding'

'Function Overriding' nuk eshte se ka ndonje perkthim te drejtperdrejt ne shqip, por ka te beje me refuzimin e funksioneve qe trashegohen nga klasa prind dhe zevendesimi me funksione te reja me te njejtin emer. Pra, emri dhe numri i argumenteve mbetet e njejte me ate te klases prind, por mund te ndryshojme trupin e funksionit. Kjo behet per arsye se ne shume raste tek klasat femije duam te personalizojme nje funksion, t'ja pershtasim klases aktuale.

P.sh. le te perdorim 'Function Overriding' ne klasen Zog:

<?php

clas Zog extends Kafshe {

    function merr_frym() {
        print ("Zogu thith oskigjen.");
    }

    function fluturon() {
        print("Fluturon ne qiell.");
    }
}

Ne shembullin e mesiperm, pavaresisht se funksioni merr_frym trashegohet nga klasa prind Kafshe, ne e kemi deklaruar perseri. Ne kete rast kemi bere nje refuzim te funksionit te klases prind, duke deklaruar nje te ri. Kur te therritet funksioni $zog->merr_frym();, eshte funksioni i ri i deklaruar ne klases Zog ai qe do te therritet, dhe jo funksioni i deklaruar ne klasen prind.

Duhet te kemi kujdes pasi ne rast se duam te perdorim konceptin e 'Overriding', funksionet e rideklaruara ne klasen femije nuk duhet te ndryshojne:

  • emrin e funksionit
  • numrin e argumenteve qe pranojne
  • modifikuesin e aksesit public, private apo protected (te cilat do te shpjegohen ne vijim)

Ndonjehere eshte e nevojshme qe pervecse te therritet funksioni i ri i deklaruar ne klasen femije, duam qe te therritet edhe funksioni i deklaruar ne klasen prind. Ajo cfare perdorim eshte nje term i quajtur parent, te cilin duke e shoqeruar me simbolin :: dhe me emrin e funksionit, do te therrase edhe funksionin e klases prind.

Shembull:

<?php

clas Zog extends Kafshe {

    function merr_frym() {

        //Do te therrase funksionin `merr_frym()` te klases `Kafshe`
        parent::merr_frym();

        print ("Zogu thith oskigjen.");
    }

    function fluturon() {
        print("Fluturon ne qiell.");
    }
}

Ne momentin qe therrasim metoden $zog->merr_frym();, ajo cfare do te na printohet ne ekran eshte:

Thith oksigjenin qe ndodhet ne ajer.Zogu thith oskigjen.

Arsyeja eshte se ne momentin qe therritet funksioni merr_frym i klases Zog, ne trupin e funksionit deklarata parent::merr_frym(); do te therrase funksionin merr_frym te klases Kafshe qe printon Thith oksigjenin qe ndodhet ne ajer.. Me pas do te vazhdoje ekzekutimi i funksionit merr_frym te klases Zog ku do te printohet Zogu thith oskigjen.

parent:: perdoret edhe kur duam te therrasim konstruktorin e klases prind.

<?php

class Makine {

    public $shpejtesia;

    function __construct() {
        print("U therrit konstruktori i klases Makine! <br>");
    }
}

class Autobus extends Makine {

    function __construct() {

        //Therrasim konstruktorin e klases prind
        parent::__construct();

        print("U therrit konstruktori i klases Autobus!");
    }
}

$autobus = new Autobus();

Ne momentin e krijimit te objektit $autobus do te therritet menjehere konstruktori i klases Autobus. Por brenda ketij konstruktori gjendet shprehja parent::__construct() e cila therret konstruktorin e klases prind Makine. Si rezultat do te printohet:

U therrit konstruktori i klases Makine!
U therrit konstruktori i klases Autobus!

Termi final

Ndonjehere kur ne krijojme ndonje klase, te tjeret mund ta perdorin ate dhe ta trashegojne duke krijuar klase femije. Ndoshta eshte e nevojshme qe per disa metoda te kesaj klase te parandalojme qe te behen override ne klasat femije. Kjo realizohet duke shtuar para deklarimit te funksioneve termin final.

Shembull:

<?php

class Muzikant {

    protected $emri;

    public function __construct($emri)
    {
        $this->emri = $emri;
    }

    public function getEmri()
    {
        return $this->emri;
    }

    //Parandalon qe klasat femije ti bejne override
    final public function luaj_muzike()
    {
        return $this->emri . " po luan muzike!";
    }
}


class Kitarist extends Muzikant {

    public function getEmri()
    {
        return "Emri im eshte " . $this->emri;
    }
}

Ne shembullin e mesiperm kemi krijuar nje klase prind Muzikant dhe nje klase femije Kitarist. Klasa Kitarist i ka bere override funksionit getEmri() duke e ndryshuar pak. Klasa Kitarist e ka te pamundur t'i beje override metodes luaj_muzike() sepse ajo eshte deklaruar final ne klasen prind.

<?php

$muzikant = new Muzikant("Shpetim Saraci");

echo $muzikant->getEmri();    //Rezultati: Shpetim Saraci

echo $muzikant->luaj_muzike();    //Rezultati: Shpetim Saraci po luan muzike!


$kitarist = new Kitarist("John Lee");

echo $kitarist->getEmri();    //Rezultati: Emri im eshte John Lee

echo $kitarist->luaj_muzike();    //Rezultati: John Lee po luan muzike!

Deklarimi i nje klase final parandalon trashegimin e saj. Ajo nuk mund te trashegohet.

<?php

final class Muzikant {

    private $emri;

   final public function luaj_muzike() {
        return $this->emri . " po luan muzike!";
   }
}

Nuk ka ndonje rendesi te vecante nqs. deklarojme metodat final pasi ato detyrimisht nuk mund te behen override, dukeqenese klasa nuk mund te trashegohet. Ne rast se provojme te trashegojme nje klase te tille, do te gjenerohet gabim nga PHP-ja.

results matching ""

    No results matching ""